/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Servidor;

import Logica.Casilla;
import Logica.Ficha;
import Presentacion.InterfaceRemota;
import Logica.Jugador;
import Logica.Tablero;
import Presentacion.Board;
import Presentacion.Principal; 
import java.rmi.*;
import java.rmi.registry.*;
import java.rmi.server.*;
import java.net.*;
import java.util.ArrayList;
import java.util.Random;
 

/**
 * Clase encargada de los métodos necesarios para que funcione el servidor del juego, 
 * implementa la clase [@InterfaceRemota]
 * @author JuanJo
 */

public class ScrabbleServidor extends java.rmi.server.UnicastRemoteObject
implements InterfaceRemota
{
    int      thisPort;
    String   thisAddress;
    Registry registry;
    Principal principal;
    
    
    // rmi registry for lookup the remote objects. 
    // This method is called from the remote client by the RMI.
    // This is the implementation of the �gReceiveMessageInterface�h.    
 
    /**
     * Constructor de la clase
     * @throws RemoteException 
     */
    
    public ScrabbleServidor() throws RemoteException
    {
        try{
            // get the address of this host.
            thisAddress = (InetAddress.getLocalHost()).toString();
        }
        catch(Exception e){
            throw new RemoteException("can't get inet address.");
        }
            thisPort=3232;  // this port(registry�fs port)
            System.out.println("this address="+thisAddress+",port="+thisPort);
        try{
            // create the registry and bind the name and object.
            registry = LocateRegistry.createRegistry( thisPort );
            registry.rebind("rmiServer", this);
            
            iniciarTablero(); 
            iniciarSaco();                       
            
        }
        catch(RemoteException e){
            throw e;
        }
    }
   
    /**
     * Método principal de la clase
     * @param args parámetro por default.
     */
    
    static public void main(String args[])
    {
        try{
            ScrabbleServidor s = new ScrabbleServidor();            
            
    }
    catch (Exception e) {
           e.printStackTrace();
           System.exit(1);
    }
     }
        
     /**
     * Asigna a las casillas del tablero de juego sus diferentes valores iniciales
     */
    
    public void iniciarTablero(){
        
        Tablero.getInstancia().getInfoTablero();
        
        for (int i = 0; i < Tablero.getInstancia().getInfoTablero().length; i++) {
            for (int j = 0; j < Tablero.getInstancia().getInfoTablero().length; j++) {
                
                boolean ninguna = true;
                Tablero.getInstancia().getInfoTablero()[i][j]= new Casilla();
                                
                //Triple Valor de Palabra (+)
                if((i==0 && j==0) || (i==7 && j==0) || (i==14 && j==0) || (i==0 && j==7) 
                  || (i==14 && j==7) || (i==0 && j==14) || (i==7 && j==14) || (i==14 && j==14)){  
                      Ficha ficha = new Ficha("+",0);                      
                      Tablero.getInstancia().getInfoTablero()[i][j].setEjeX(i);
                      Tablero.getInstancia().getInfoTablero()[i][j].setEjeY(j);
                      ninguna = false;
                      //Tablero.getInstancia().getInfoTablero()[i][j].setImagenCasilla(new javax.swing.ImageIcon("Imagenes\tp.png"));
                      Tablero.getInstancia().getInfoTablero()[i][j].setFicha(ficha);
                }
                //Doble Valor de Letra (-)
                if((i==3 && j==0) || (i==11 && j==0) || (i==6 && j==2) || (i==8 && j==2) || (i==0 && j==3)
                  || (i==7 && j==3) || (i==14 && j==3) || (i==2 && j==6) || (i==6 && j==6) || (i==8 && j==6) 
                  || (i==12 && j==6) || (i==3 && j==7) || (i==11 && j==7) || (i==2 && j==8) || (i==6 && j==8) 
                  || (i==8 && j==8) || (i==12 && j==8) || (i==0 && j==11) || (i==7 && j==11) || (i==14 && j==11) 
                  || (i==6 && j==12) || (i==8 && j==12) || (i==3 && j==14) || (i==11 && j==14)){    
                       Ficha ficha = new Ficha("-",0);                       
                       Tablero.getInstancia().getInfoTablero()[i][j].setEjeX(i);
                       Tablero.getInstancia().getInfoTablero()[i][j].setEjeY(j);
                       ninguna = false;
                       //Tablero.getInstancia().getInfoTablero()[i][j].setImagenCasilla(new javax.swing.ImageIcon("Imagenes\tdl.png"));
                       Tablero.getInstancia().getInfoTablero()[i][j].setFicha(ficha);
                }
                //Doble Valor de Palabra (*)
                if((i==1 && j==1) || (i==13 && j==1) || (i==2 && j==2) || (i==12 && j==2) || (i==3 && j==3) ||
                   (i==11 && j==3) || (i==4 && j==4) || (i==10 && j==4) || (i==7 && j==7) || (i==4 && j==10) ||
                   (i==10 && j==10) || (i==3 && j==11) || (i==11 && j==11) || (i==2 && j==12) || (i==12 && j==12) ||
                   (i==1 && j==13) || (i==13 && j==13)){
                       Ficha ficha = new Ficha("*",0);
                       Tablero.getInstancia().getInfoTablero()[i][j].setEjeX(i);
                       Tablero.getInstancia().getInfoTablero()[i][j].setEjeY(j);    
                       ninguna = false;
                       //Tablero.getInstancia().getInfoTablero()[i][j].setImagenCasilla(new javax.swing.ImageIcon("Imagenes\tdp.png"));
                       Tablero.getInstancia().getInfoTablero()[i][j].setFicha(ficha);
                }
                //Triple Valor de Letra (/)
                if((i==5 && j==1) || (i==9 && j==1) || (i==1 && j==5) || (i==5 && j==5) || (i==9 && j==5) ||
                  (i==13 && j==5) || (i==1 && j==9) || (i==5 && j==9) || (i==9 && j==9) || (i==13 && j==9) ||
                  (i==5 && j==13) || (i==9 && j==13)){
                       Ficha ficha = new Ficha("/",0);
                       Tablero.getInstancia().getInfoTablero()[i][j].setEjeX(i);
                       Tablero.getInstancia().getInfoTablero()[i][j].setEjeY(j); 
                       ninguna = false;
                       //Tablero.getInstancia().getInfoTablero()[i][j].setImagenCasilla(new javax.swing.ImageIcon("Imagenes\tl.png"));
                       Tablero.getInstancia().getInfoTablero()[i][j].setFicha(ficha);
                }
                
                if(ninguna){
                   Ficha ficha = new Ficha(".",0);
                   Tablero.getInstancia().getInfoTablero()[i][j].setEjeX(i);
                   Tablero.getInstancia().getInfoTablero()[i][j].setEjeY(j); 
                   //Tablero.getInstancia().getInfoTablero()[i][j].setImagenCasilla(new javax.swing.ImageIcon("Imagenes\tsola.png"));
                   Tablero.getInstancia().getInfoTablero()[i][j].setFicha(ficha);
                }                                
                                           
                System.out.println(Tablero.getInstancia().getInfoTablero()[i][j].getFicha().getLetra());
            }
        }        
    } 
    
    /**
     * Inicializa los componentes del saco del juego.
     */
    
    public void iniciarSaco(){
         
        Tablero.getInstancia().getSaco();
        
        for(int i = 0; i<12; i++){
            
            if(i<12){
               Ficha f1 = new Ficha("a",1);
               Ficha f2 = new Ficha("e",1);
               Tablero.getInstancia().getSaco().getFichas().add(f1);
               Tablero.getInstancia().getSaco().getFichas().add(f2);
            }
            if(i<9){
               Ficha f1 = new Ficha("o",1);
               Tablero.getInstancia().getSaco().getFichas().add(f1);
            }
            
            if(i<6){
               Ficha f1 = new Ficha("i",1);
               Ficha f2 = new Ficha("s",1);
               Tablero.getInstancia().getSaco().getFichas().add(f1);
               Tablero.getInstancia().getSaco().getFichas().add(f2);
            }
            if(i<5){
               Ficha f1 = new Ficha("n",1);
               Ficha f2 = new Ficha("u",1);
               Ficha f3 = new Ficha("d",2);
               Ficha f4 = new Ficha("r",1);
               Tablero.getInstancia().getSaco().getFichas().add(f1);
               Tablero.getInstancia().getSaco().getFichas().add(f2);
               Tablero.getInstancia().getSaco().getFichas().add(f3);
               Tablero.getInstancia().getSaco().getFichas().add(f4);
            }
            if(i<4){
               Ficha f1 = new Ficha("c",3);               
               Ficha f3 = new Ficha("l",1);               
               Ficha f5 = new Ficha("t",1);
               Tablero.getInstancia().getSaco().getFichas().add(f1);
               Tablero.getInstancia().getSaco().getFichas().add(f3);               
               Tablero.getInstancia().getSaco().getFichas().add(f5);
            }
            if(i<2){
               
               Ficha f2 = new Ficha("g",2);
               Ficha f3 = new Ficha("h",4);               
               Ficha f5 = new Ficha("p",3);               
               Ficha f7 = new Ficha("bla",0);
               Ficha f8 = new Ficha("b",3);
               Ficha f9 = new Ficha("m",3);
               
               Tablero.getInstancia().getSaco().getFichas().add(f2);
               Tablero.getInstancia().getSaco().getFichas().add(f3);               
               Tablero.getInstancia().getSaco().getFichas().add(f5);
               
               Tablero.getInstancia().getSaco().getFichas().add(f7);
               Tablero.getInstancia().getSaco().getFichas().add(f8);
               Tablero.getInstancia().getSaco().getFichas().add(f9);
            } 
            if(i<1){
               
               Ficha f2 = new Ficha("ll",8);
               Ficha f3 = new Ficha("ñ",8);
               Ficha f4 = new Ficha("q",5);
               Ficha f5 = new Ficha("rr",8);               
               Ficha f7 = new Ficha("x",8);
               Ficha f8 = new Ficha("y",4);
               Ficha f9 = new Ficha("z",10);
               Ficha f10 = new Ficha("f",4);
               Ficha f11 = new Ficha("j",8);
               Ficha f12 = new Ficha("v",4);
               Ficha f13 = new Ficha("ch",5);
               
               Tablero.getInstancia().getSaco().getFichas().add(f2);
               Tablero.getInstancia().getSaco().getFichas().add(f3);
               Tablero.getInstancia().getSaco().getFichas().add(f4);
               Tablero.getInstancia().getSaco().getFichas().add(f5);               
               Tablero.getInstancia().getSaco().getFichas().add(f7);
               Tablero.getInstancia().getSaco().getFichas().add(f8);
               Tablero.getInstancia().getSaco().getFichas().add(f9);
               Tablero.getInstancia().getSaco().getFichas().add(f10);
               Tablero.getInstancia().getSaco().getFichas().add(f11);
               Tablero.getInstancia().getSaco().getFichas().add(f12);
               Tablero.getInstancia().getSaco().getFichas().add(f13);
            } 
            
        System.out.println(Tablero.getInstancia().getSaco().getFichas().size());
        }      
        
        //A cada ficha le pone un ID_FICHA
        for(int i = 0; i<Tablero.getInstancia().getSaco().getFichas().size();i++){
            Tablero.getInstancia().getSaco().getFichas().get(i).setId_ficha(i);
        }
    
    }
    
    /**
     * Devuelve un atributo de tipo Tablero la instancia del tablero al cliente.
     * @return Tablero con los componentes listos para la partida (Singleton).
     * @throws RemoteException 
     */
    
    @Override
    public Tablero getTablero() throws RemoteException {
        return Tablero.getInstancia();       
        
    }
    
    /**
     * Devuelve un atributo de tipo entero el identificar del jugador creado a partir de los parámetros String de nombre y personaje
     * @param nombre que tendrá el jugador durante la partida
     * @param personaje que tendrá el jugador durante la partida
     * @return Confirmación de jugador creado
     * @throws RemoteException 
     */
    @Override
    public int crearJugador(String nombre, String personaje) throws RemoteException {
       
       //boolean confirmacion = false;  
       
           Jugador jugador = new Jugador();
           jugador.setNombre(nombre);
           jugador.setPersonaje(personaje);
           jugador.setJugador_id(Tablero.getInstancia().getJugadores().size());
           System.out.println("Fichas en el Saco : "+Tablero.getInstancia().getSaco().getFichas().size());
           
           //Escojer 7 fichas del saco al azar para el Jugador
           for(int i = 0; i<7 ; i++){
               Random rand = new Random();
               int index = rand.nextInt(Tablero.getInstancia().getSaco().getFichas().size());
               jugador.getAtril().getFichas().add(Tablero.getInstancia().getSaco().getFichas().get(index));
               System.out.println("Ficha "+i+" : "+jugador.getAtril().getFichas().get(i).getLetra());
               Tablero.getInstancia().getSaco().getFichas().remove(index);
               System.out.println("Fichas en el Saco : "+Tablero.getInstancia().getSaco().getFichas().size());
           }                 
           
           Tablero.getInstancia().getJugadores().add(jugador);           
           System.out.println(jugador.getNombre());          
           //confirmacion = true;
       
       return jugador.getJugador_id();
    }  
    
    /*
     * Cambia las fichas del atril con las fichas contenidas en el saco del identificador del jugador recibido por parámetro
     */

    @Override
    public void cambiarAtril(int idJugador) throws RemoteException{
          
        for(int i=0; i < Tablero.getInstancia().getJugadores().size(); i++){
            if(Tablero.getInstancia().getJugadores().get(i).getJugador_id() == idJugador){
                //Retornar las fichas del jugador al saco
                for(int j = 0 ; j < Tablero.getInstancia().getJugadores().get(i).getAtril().getFichas().size(); j++){
                    Tablero.getInstancia().getSaco().getFichas().add(Tablero.getInstancia().getJugadores().get(i).getAtril().getFichas().get(j));
                }
                //Se vacia el atril del jugador
                Tablero.getInstancia().getJugadores().get(i).getAtril().getFichas().clear();
                
                //Se llena el atril con nuevas fichas aleatorias               
               for(int j = 0; j<7 ; j++){
                    Random rand = new Random();
                    int index = rand.nextInt(Tablero.getInstancia().getSaco().getFichas().size());
                    Tablero.getInstancia().getJugadores().get(i).getAtril().getFichas().add(Tablero.getInstancia().getSaco().getFichas().get(index));
                    Tablero.getInstancia().getSaco().getFichas().remove(index);
                    System.out.println("Fichas en el Saco : "+Tablero.getInstancia().getSaco().getFichas().size());
               } 
            }
        }
        
    
    }
    
    /*
     * Cambia la ficha escogida por el cliente y actualiza el atril del jugador con una ficha nueva de la bolsa
     */
    
    @Override
    public void cambiarFicha(int idJugador, String fichaEscogida) throws RemoteException{
        for(int i=0; i < Tablero.getInstancia().getJugadores().size(); i++){
            if(Tablero.getInstancia().getJugadores().get(i).getJugador_id() == idJugador){
               //Recorrer el atril para encontra la ficha a cambiar
                for(int j = 0; j < Tablero.getInstancia().getJugadores().get(i).getAtril().getFichas().size(); j++){
                    if(Tablero.getInstancia().getJugadores().get(i).getAtril().getFichas().get(j).getLetra().equals(fichaEscogida)){
                        Tablero.getInstancia().getJugadores().get(i).getAtril().getFichas().remove(j);
                        
                        Random rand = new Random();
                        int index = rand.nextInt(Tablero.getInstancia().getSaco().getFichas().size());
                        Tablero.getInstancia().getJugadores().get(i).getAtril().getFichas().add(j,Tablero.getInstancia().getSaco().getFichas().get(index));                
                        Tablero.getInstancia().getSaco().getFichas().remove(index);
                    }
                }                          
            }
        }      
    }
    
    /*
     * Actualiza el tablero con los cambios realizados por el cliente y realiza el calculo del puntaje del jugador de acuerdo a la jugada realizada.
    */
    
    @Override
    public void setTablero(ArrayList<Casilla> palabraNueva, int idJugador) throws RemoteException{
       
        //Asignar a la palabraNueva las fichas reales del atril del jugador
        for(int i = 0 ; i < Tablero.getInstancia().getJugadores().size(); i++){
            if(Tablero.getInstancia().getJugadores().get(i).getJugador_id() == idJugador){
                
                for(int k = 0; k < palabraNueva.size(); k++){
                   for(int j = 0 ; j < Tablero.getInstancia().getJugadores().get(i).getAtril().getFichas().size(); j++){     
                        if(Tablero.getInstancia().getJugadores().get(i).getAtril().getFichas().get(j).getLetra().equals(palabraNueva.get(k).getFicha().getLetra())){
                            
                            palabraNueva.get(k).setFicha(Tablero.getInstancia().getJugadores().get(i).getAtril().getFichas().get(j));
                            Tablero.getInstancia().getJugadores().get(i).getAtril().getFichas().remove(j);
                            
                        }
                   }
                }                
            }
            //Llenar el atril del jugador para completar las 7 fichas iniciales con letras aleatorias            
            while(Tablero.getInstancia().getJugadores().get(i).getAtril().getFichas().size() < 7){
                Random rand = new Random();
                int index = rand.nextInt(Tablero.getInstancia().getSaco().getFichas().size());
                Tablero.getInstancia().getJugadores().get(i).getAtril().getFichas().add(Tablero.getInstancia().getSaco().getFichas().get(index));                
                Tablero.getInstancia().getSaco().getFichas().remove(index);
            }
            
            //Actualizar el tablero original con la nueva palabra y calcular el puntaje del jugador
            int puntajeJugada = 0;
            int doblePalabra = 0;
            int triplePalabra = 0;
                
            for(int j = 0; j < palabraNueva.size() ; j++){              
                
                int ejex = palabraNueva.get(j).getEjeX();
                int ejey = palabraNueva.get(j).getEjeY();
                
                if(Tablero.getInstancia().getInfoTablero()[ejex][ejey].getFicha().getLetra().equals("*")){
                    puntajeJugada = puntajeJugada + palabraNueva.get(j).getFicha().getCosto();
                    doblePalabra++;
                                       
                }
                if(Tablero.getInstancia().getInfoTablero()[ejex][ejey].getFicha().getLetra().equals("+")){
                    puntajeJugada = puntajeJugada + palabraNueva.get(j).getFicha().getCosto();
                    triplePalabra++;
                    
                }
                if(Tablero.getInstancia().getInfoTablero()[ejex][ejey].getFicha().getLetra().equals("-")){
                    puntajeJugada = puntajeJugada + (palabraNueva.get(j).getFicha().getCosto()*2);
                    
                }
                if(Tablero.getInstancia().getInfoTablero()[ejex][ejey].getFicha().getLetra().equals("/")){
                    puntajeJugada = puntajeJugada + (palabraNueva.get(j).getFicha().getCosto()*3);
                    
                } 
                if(Tablero.getInstancia().getInfoTablero()[ejex][ejey].getFicha().getLetra().equals(".")){
                    puntajeJugada = puntajeJugada + palabraNueva.get(j).getFicha().getCosto();
                    
                }
                //Si el tablero tiene una letra de la palabra nueva desde antes, solo se le suma el costo
                //de la letra al puntajeJugada sin el premio que pueda existir en esa casilla
                if((!Tablero.getInstancia().getInfoTablero()[ejex][ejey].getFicha().getLetra().equals("/"))&&
                  (!Tablero.getInstancia().getInfoTablero()[ejex][ejey].getFicha().getLetra().equals("*"))&&
                  (!Tablero.getInstancia().getInfoTablero()[ejex][ejey].getFicha().getLetra().equals("-"))&&
                  (!Tablero.getInstancia().getInfoTablero()[ejex][ejey].getFicha().getLetra().equals("+"))&&
                  (!Tablero.getInstancia().getInfoTablero()[ejex][ejey].getFicha().getLetra().equals("."))){
                    
                    puntajeJugada = puntajeJugada + palabraNueva.get(j).getFicha().getCosto();
                
                }
            Tablero.getInstancia().getInfoTablero()[ejex][ejey].setFicha(palabraNueva.get(j).getFicha());     
            System.out.println("Puntaje jugada 1 : "+puntajeJugada);    
                
            }
            
            for(int j = 0; j < doblePalabra; j++){
                puntajeJugada = puntajeJugada*2;
            }
            for(int j = 0; j < triplePalabra; j++){
                puntajeJugada = puntajeJugada*3;
            }
            System.out.println("Puntaje jugada : "+puntajeJugada);
            puntajeJugada = puntajeJugada + Tablero.getInstancia().getJugadores().get(i).getPuntaje();
            Tablero.getInstancia().getJugadores().get(i).setPuntaje(puntajeJugada);    
            System.out.println("PUNTAJE ACTUAL JUGADOR "+idJugador+" : "+Tablero.getInstancia().getJugadores().get(i).getPuntaje());
        }
        
        
        
    }
    
    
    
    
}

